﻿// © Benn Eichhorn 2010
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Algobox.Feeds.Finance.Chix.CHIXMD.Messages
{
    /// <summary>
    /// Singleton Chi-X Order Cancel message
    /// </summary>
    public class OrderCancel : IMessage
    {
        private OrderCancel() { }

        private static OrderCancel m_Instance = new OrderCancel();

        /// <summary>
        /// Get's the singleton instance of the OrderCancel class
        /// </summary>
        /// <returns>Current OrderCancel</returns>
        public static OrderCancel GetInstance() { return m_Instance; }

        public char MessageType { get { return 'S'; } }
        
        /// <summary>
        /// Milliseconds since midnight
        /// </summary>
        public int TimeStampMillis;

        /// <summary>
        /// Slow, calculates current TimeStamp from TimeStampMillis
        /// </summary>
        public DateTime TimeStamp { get { return MessageParser.Date.AddMilliseconds(TimeStampMillis); } }

        /// <summary>
        /// The reference number of the order being canceled, references a previously sent OrderAdd message
        /// </summary>
        public int OrderReference;
        
        /// <summary>
        /// Number of shares canceled
        /// </summary>
        public ulong CanceledShares;
                
        public override string ToString()
        {
            return String.Format("IMessage->OrderCancel: OrderReference={0},CanceledShares={1},TimeStamp={2}", OrderReference, CanceledShares, TimeStamp);
        }


        // Order Cancel
        const int S_X_LEN = 25;
        const int S_X_ORDERREF_LOC = 10;
        const int S_X_ORDERREF_LEN = 9;
        const int S_X_SHARES_LOC = 19;
        const int S_X_SHARES_LEN = 6;

        // Order Cancel Long
        const int S_x_LEN = 29;
        const int S_x_ORDERREF_LOC = 10;
        const int S_x_ORDERREF_LEN = 9;
        const int S_x_SHARES_LOC = 19;
        const int S_x_SHARES_LEN = 10;


        internal static IMessage ParseShort(ref string inbound)
        {
            // get sequenced data message timestamp
            if (!Int32.TryParse(inbound.Substring(MessageParser.S_TIMESTAMP_LOC, MessageParser.S_TIMESTAMP_LEN), out m_Instance.TimeStampMillis))
            {
                Messages.Error message = Messages.Error.GetInstance("Sequenced data message failed to parse TimeStamp millis as Double", inbound);
                return message;
            }


            if (!Int32.TryParse(inbound.Substring(S_X_ORDERREF_LOC, S_X_ORDERREF_LEN), out m_Instance.OrderReference))
            {
                return Messages.Error.GetInstance("OrderCancel (long) failed to parse OrderReference as Int32", inbound);
            }
            if (!UInt64.TryParse(inbound.Substring(S_X_SHARES_LOC, S_X_SHARES_LEN), out m_Instance.CanceledShares))
            {
                return Messages.Error.GetInstance("OrderCancel (long) failed to parse CanceledShares as Int32", inbound);
            }

            return m_Instance;
        }


        internal static IMessage ParseLong(ref string inbound)
        {
            // get sequenced data message timestamp
            if (!Int32.TryParse(inbound.Substring(MessageParser.S_TIMESTAMP_LOC, MessageParser.S_TIMESTAMP_LEN), out m_Instance.TimeStampMillis))
            {
                Messages.Error message = Messages.Error.GetInstance("Sequenced data message failed to parse TimeStamp millis as Double", inbound);
                return message;
            }

            if (!Int32.TryParse(inbound.Substring(S_x_ORDERREF_LOC, S_x_ORDERREF_LEN), out m_Instance.OrderReference))
            {
                return Messages.Error.GetInstance("OrderCancel (long) failed to parse OrderReference as Int32", inbound);                
            }
            if (!UInt64.TryParse(inbound.Substring(S_x_SHARES_LOC, S_x_SHARES_LEN), out m_Instance.CanceledShares))
            {
                return Messages.Error.GetInstance("OrderCancel (long) failed to parse CanceledShares as Int32", inbound);                
            }

            return m_Instance;
        }


        /// <summary>
        /// Deep clone
        /// </summary>
        /// <returns></returns>
        public OrderCancel Clone()
        {
            OrderCancel clone = new OrderCancel();
            clone.CanceledShares = m_Instance.CanceledShares;
            clone.OrderReference = m_Instance.OrderReference;
            clone.TimeStampMillis = m_Instance.TimeStampMillis;
            return clone;
        }
    }
}
